<template>
  <div class="select-search">
    <el-select
      :id="`form_${field.fieldName}`"
      popper-class="advanced-search-remote-select-search-popper"
      :value="selectValue"
      :placeholder="placeholder"
      :multiple="multiple || field.fieldName === 'role'"
      :remote-method="keywordSearch"
      remote
      clearable
      filterable
      collapse-tags
      v-el-select-loadmore="loadMoreOptions"
      @focus="focus"
      @input="changeSelect"
    >
      <el-option
        v-for="item in options"
        :key="item.key || item.value"
        :label="item.label"
        :value="item"
        :style="{'width': minWidth + 2 + 'px'}"
      >
      </el-option>
    </el-select>
  </div>
</template>

<script>
import { defineComponent, computed, ref, watch } from 'vue';
import { debounce } from 'lodash';
import i18n from '@src/locales';
import { isObject } from '@src/util/type'

export default defineComponent({
  name: 'remote-select-search',
  props: {
    field: {
      type: Object,
      default: null,
    },
    placeholder: {
      type: String,
      default: i18n.t('common.placeholder.inputKeyWordToSearch'),
    },
    value: {
      type: [Number, String, Array, Object],
      default: '',
    },
    multiple: {
      type: Boolean,
      default: false,
    },
    remoteMethod: {
      type: Function,
      default: null,
    },
  },
  emits: ['update'],
  setup(props, { emit }) {
    const isRoleField = computed(() => {
      return props.field?.fieldName === 'role';
    });
    const selectValue = ref(Array.isArray(props.value) ? [...props.value] : props.value)
    const minWidth = ref(275)
    watch(
      () => props.value,
      () => {
        if (selectValue.value !== props.value) {
          Array.isArray(props.value) ? (selectValue.value = [...props.value]) : (selectValue.value = props.value)
        }
      }
    );
    const options = ref(
      props.value
        ? Array.isArray(props.value)
          ? [...props.value]
          : [props.value]
        : []
    );

    ;(async ()=> {
      try {
        if(isRoleField) {
          const { status, data } = await props.remoteMethod();
          if(status == 0) {
            options.value = data || []
            if(props.value && props.value.length && !isObject(props.value[0])) {
              // 角色字段后端返回的是字符串数组 需要转成对象数组
              let roleList = []
              for (let i = 0; i < props.value.length; i++) {
                const role = options.value.find(item=>item.value == props.value[i])
                roleList.push(role)
              }
              selectValue.value = roleList
            }
          } 
        }
      } catch (error) {
        console.log('error', error)
      }
    })();

    const searchParams = ref({
      keyword: '',
      pageNum: 1,
    });
    const loading = ref(false);

    const hasNextPage = ref(true);

    // 改变值
    function changeSelect(value) {
      if(isRoleField) selectValue.value = value
      emit('update', value);
    }

    function keywordSearch(keyword = '') {
      searchParams.value.keyword = keyword;
      searchParams.value.pageNum = 1;
      search();
    }

    const search = debounce(async () => {
      if (loading.value) return;
      if (!props.remoteMethod) return console.warn('请提供查询方法');
      try {
        loading.value = true;
        const res = await props.remoteMethod(searchParams.value);
        if (searchParams.value.pageNum === 1) {
          options.value = [];
        }
        // 兼容知识库获取角色列表接口返回的数据格式
        if(props.field.fieldName === 'role') {
          res.list = res.data || [];
        }
        options.value.push(...res.list);
        hasNextPage.value = res.hasNextPage;
      } catch (error) {
      } finally {
        loading.value = false;
      }
    }, 500);

    function focus(val) {
      if (options.value.length) return;
      keywordSearch();
      minWidth.value = val.srcElement.clientWidth
    }

    const loadMore = debounce(() => {
      if (!hasNextPage.value || loading.value) return;
      searchParams.value.pageNum++;
      search();
    });

    const loadMoreOptions = computed(() => ({
      disabled: false,
      callback: loadMore,
      distance: 10,
    }));

    return {
      isRoleField,
      selectValue,
      loadMoreOptions,
      options,
      minWidth,

      changeSelect,
      focus,
      keywordSearch,
      loadMore,
    };
  },
});
</script>

<style lang="scss">
.advanced-search-remote-select-search-popper {
  .el-select-dropdown__item {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}
</style>
